﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using Castle.Core;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Dexter.Dependency.Installation;
using Component = Castle.MicroKernel.Registration.Component;

namespace Dexter.Dependency.Castle {
	public class CastleInstaller : IDexterInstaller {
		#region IDexterInstaller Members

		public IEnumerable <ILayerInstaller> GetInstallers ( IEnumerable <Assembly> assemblies ) {
			WindsorContainer builder = new WindsorContainer ( );

			foreach ( var assembly in assemblies ) {
				Register ( assembly , builder );
			}

			return builder.ResolveAll <ILayerInstaller> ( );
		}

		#endregion

		void Register ( Assembly assembly , WindsorContainer container ) {
			Type baseClass = typeof(ILayerInstaller);

			IEnumerable<Type> types = from c in assembly.GetTypes()
									  where !c.IsAbstract && baseClass.IsAssignableFrom(c)
									  select c;

			foreach (Type type in types)
			{
				if (type == null || string.IsNullOrEmpty(type.FullName))
				{
					continue;
				}

				ComponentRegistration<object> component = Component.For(baseClass)
						.ImplementedBy(type)
						.Named(type.FullName)
						.LifeStyle.Is(LifestyleType.Singleton);

				container.Register(component);
			}
		}
	}
}